package questions;

public class Q2SingletonQuestion {
    private static volatile   Boolean flag=false;

    public static void main(String[] args) {
//        System.out.println(Singleton1.INSTANCE);
//        System.out.println(Singleton2.INSTANCE);
        Long runTimes = 0L;
        while (testSingleton5()) {
            flag = false;
            runTimes++;
        }
        System.out.println("执行结束,第：" + runTimes + "次");
    }
    public static boolean testSingleton5(){
        try {
            for (Integer i = 0; i < 15; i++) {
                new Thread(() -> {
                    while (!flag) {
                    }
                    Singleton5 singleton5 = Singleton5.getInstance();
                    singleton5.test();
                }).start();
            }
            flag = true;
            while (Thread.activeCount() > 2) {
                Thread.yield();
            }
//            System.out.println("执行结束");
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;
        }
        return true;
    }
}

/**
 * 懒汉式
 * 有多线程安全问题
 */
class Singleton6 {
    private Singleton6() {
    }

    public static Singleton6 getInstance() {
        return Inner.INSTANCE;
    }

    public static class Inner {
        private static final Singleton6 INSTANCE = new Singleton6();
    }
}

/**
 * 懒汉式
 * 有多线程安全问题
 */
class Singleton5 {
    private static Singleton5 INSTANCE;

    private Singleton5() {
//        System.out.println("Singleton5 初始化成功");
    }
    public void test(){

    }

    public static Singleton5 getInstance() {
        if (INSTANCE == null) {
            synchronized (Singleton5.class) {
                if (INSTANCE == null) {
                    INSTANCE = new Singleton5();
                }
            }
        }
        return INSTANCE;
    }
}

/**
 * 懒汉式
 * 有多线程安全问题
 */
class Singleton4 {
    private static Singleton4 INSTANCE;

    private Singleton4() {
    }

    public static Singleton4 getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new Singleton4();
        }
        return INSTANCE;
    }
}

/**
 * 恶汉式
 * 无论是否需要，直接创建对象
 * 1、构造器私有化
 * 2、自行创建对象
 * 3、向外提供实例
 * 4、强调这个实例是单例，申明为final
 */
class Singleton1 {
    public static final Singleton1 INSTANCE = new Singleton1();

    private Singleton1() {
    }
}

/**
 * 恶汉式
 * 无论是否需要，直接创建对象
 * 1、构造器私有化
 * 2、自行创建对象
 * 3、向外提供实例
 * 4、强调这个实例是单例，申明为final
 */
class Singleton3 {
    public static final Singleton3 INSTANCE;

    static {
        //假如需要从外部读取信息来调用构造函数
        INSTANCE = new Singleton3("xxx");
    }

    private Singleton3(String info) {
    }
}

/**
 * 饿汉式
 * 枚举
 */
enum Singleton2 {
    INSTANCE;

    public void test() {

    }
}